package com.leyou.item.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.common.dto.PageDTO;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.JsonUtils;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.*;
import com.leyou.item.mapper.SpuMapper;
import com.leyou.item.service.*;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class SpuServiceImpl extends ServiceImpl<SpuMapper,Spu> implements SpuService {
    @Autowired
    private BrandService brandService;

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SpuDetailService spuDetailService;

    @Autowired
    private SkuService skuService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Override
    @Transactional
    public PageDTO<SpuDTO> queryPage(Integer page, Integer rows, Long brandId, Long categoryId,
                                     Long id, Boolean saleable) {
        page = Math.min(page, 100);
        rows = Math.max(rows,5);
        //根据条件分页查询
        Page<Spu> result = query().eq(brandId != null, "brand_id", brandId)
                .eq(categoryId != null, "cid3", categoryId)
                .eq(id != null, "id", id)
                .eq(saleable != null, "saleable", saleable)
                .page(new Page<>(page,rows));
        //将Page<Spu>转换为PageDTO<SpuDTO>方便接下来查询剩余数据
        PageDTO<SpuDTO> pageDTO = new PageDTO<>(result.getTotal(),result.getPages(),
                SpuDTO.convertEntityList(result.getRecords()));
        //根据查询结果查询出剩余的返回数据，得到新的list集合
        List<SpuDTO> spuDTOList = pageDTO.getItems().stream().map(spuDTO -> {
            spuDTO.setBrandName(brandService.getById(spuDTO.getBrandId()).getName());
            String categoryNames = categoryService.listByIds(spuDTO.getCategoryIds()).stream()
                    .map(Category::getName).collect(Collectors.joining("/"));
            spuDTO.setCategoryName(categoryNames);
            return spuDTO;
        }).collect(Collectors.toList());
        //将得到的新list集合放入pageDTO中
        pageDTO.setItems(spuDTOList);
        return pageDTO;
    }

    @Override
    @Transactional
    public void saveSpu(SpuDTO spuDTO) {
        Spu spu = spuDTO.toEntity(Spu.class);
        boolean success = save(spu);
        if(!success){
            throw new LyException(500,"商品新增失败");
        }
        SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
        SpuDetail spuDetail = spuDetailDTO.toEntity(SpuDetail.class);
        spuDetail.setSpuId(spu.getId());
        success = this.spuDetailService.save(spuDetail);
        if(!success){
            throw new LyException(500,"商品详情新增失败");
        }
        List<SkuDTO> skus = spuDTO.getSkus();
        List<Sku> skuList = skus.stream().map(skuDTO -> {
            Sku sku = skuDTO.toEntity(Sku.class);
            sku.setSpuId(spu.getId());
            return sku;
        })
                .collect(Collectors.toList());
        skuService.saveBatch(skuList);
    }

    @Override
    @Transactional
    public void updateSpuSaleable(Long id, Boolean saleable) {
        boolean success = update().eq("id", id).set("saleable", saleable).update();
        if(!success){
            throw new LyException(500,"商品上架状态更新失败");
        }
        success = skuService.update().eq("spu_id", id).eq("saleable",!saleable)
                .set("saleable", saleable).update();
        if(!success){
            throw new LyException(500,"商品详情信息上架状态更新失败");
        }

        String routingKey = saleable?"up":"down";

        this.amqpTemplate.convertAndSend("jhj",routingKey,id);
}

    @Override
    @Transactional
    public SpuDTO queryGoodsById(Long id) {
        //查询spu表,将获取到的spu存入spuDTO
        Spu spu = getById(id);
        if(spu==null){
            throw new LyException(400,"商品id不存在！");
        }
        SpuDTO spuDTO = new SpuDTO(spu);

        //查询spuDetail表将获取到的spuDetail存入spuDTO
        SpuDetail spuDetail = spuDetailService.getById(id);
        if(spuDetail==null){
            throw new LyException(400,"商品id不存在！");
        }
        spuDTO.setSpuDetail(new SpuDetailDTO(spuDetail));

        //根据spuId查询sku，将获取到的sku集合存入spuDTO
        List<Sku> skus = skuService.query().eq("spu_id", id).list();
        if(CollectionUtils.isEmpty(skus)){
            throw new LyException(400,"商品id不存在！");
        }
        List<SkuDTO> skuDTOS = skus.stream().map(sku -> new SkuDTO(sku))
                .collect(Collectors.toList());
        spuDTO.setSkus(skuDTOS);

        //根据spuDTO中的brandId查询brandName，将获取的brandName存入spuDTO
        Brand brand = this.brandService.getById(spuDTO.getBrandId());
        spuDTO.setBrandName(brand.getName());

        //根据spuDTO中的categoryId查询categoryName，将获取的categoryName存入spuDTO
        List<Category> categories = this.categoryService.listByIds(spuDTO.getCategoryIds());
        String categoryName = categories.stream().map(category -> category.getName())
                .collect(Collectors.joining("/"));
        spuDTO.setCategoryName(categoryName);
        return spuDTO;
    }

    @Override
    @Transactional
    public void updateGoods(SpuDTO spuDTO) {
        if(spuDTO.getId()!=null){
            boolean success = updateById(spuDTO.toEntity(Spu.class));
            if(!success){
                throw new LyException(500,"更新商品信息spu失败");
            }
        }
        if(spuDTO.getSpuDetail()!=null && spuDTO.getSpuDetail().getSpuId()!=null){
            boolean success = spuDetailService.save(spuDTO.getSpuDetail().toEntity(SpuDetail.class));
            if(!success){
                throw new LyException(500,"更新商品信息spuDetail失败");
            }
        }
        List<SkuDTO> skus = spuDTO.getSkus();
        if(!CollectionUtils.isEmpty(skus) && skus.size()!=0){
            Map<Boolean, List<Sku>> map = skus.stream()
                    .map(skuDTO -> skuDTO.toEntity(Sku.class))
                    .collect(Collectors.groupingBy(sku -> sku.getSaleable() == null));
            List<Sku> skusT = map.get(true);
            if(!CollectionUtils.isEmpty(skusT)){
                boolean success = skuService.saveOrUpdateBatch(skusT);
                throw new LyException(500,"更新商品信息sku失败");
            }
            List<Sku> skusF = map.get(false);
            if(!CollectionUtils.isEmpty(skusF)){
                List<Long> ids = skusF.stream().map(sku -> sku.getId()).collect(Collectors.toList());
                boolean success = skuService.removeByIds(ids);
                throw new LyException(500,"删除商品信息sku失败");
            }
        }
    }

    @Override
    public SpuDTO querySpuById(Long id) {
        Spu spu = getById(id);
        return new SpuDTO(spu);
    }
}
